module dpluginload;

import core.runtime;
version(windows){
} else {
    import core.sys.posix.dlfcn;
}
import std.string;
nothrow :
	final class DPluginLoad
	{

		this(string filename, objName){
			_fileName = filename;
			load();
		}

		~this(){close();}

		string fileName() {return _fileName;}

		bool isLoad(){return (_plug != null) && (_obj !is null);}

		bool load(){

			_plug =  Runtime.loadLibrary(filename);

			if(!_plug) {
                                _fileName = "";
				_errostr = cast(string)(fromStringz(dlerror()).dup);
				return ;
			}
			version(windows){
                            void * pfun = GetProcAddress( _plug, "_DPlugLoadCreate\0".ptr);
			} else {
                            void * pfun =  dlsym(_plug, "_DPlugLoadCreate\0".ptr);
			}
			if(pfun == null){
				_errostr = "This is a DPlug!";
				Runtime.unloadLibrary(_plug);
				_plug = null;
				return false;
			}
			return true;
		} 

	bool unLoad(){
                        if(isLoad()) {
                                Runtime.unloadLibrary(_plug);
                                _plug = null;
                                _obj = null;
                                return true;
                        }
                        return false;
                        }
		void * loadFunction(string sname)
		{
                    auto name = toStringz(sname);
                    void * pfun =  dlsym(_plug, name);
                    if(pfun == null){
                           _errostr = cast(string)(fromStringz(dlerror()).dup);
                    } 
                    return pfun;
		}

		bool isOpen() {return _plug != null;}
		
		void close(){
                    if(isOpen()) {
                        Runtime.unloadLibrary(_plug);
                        _plug = null;
                    }
                }

		string erroString(){return _errostr;}
	private:
                
	
		void * _plug = null;
		string _errostr;
		string _fileName;
	};

	
	string createrPlugin(string ifname)
	{
            string str = "extern (C) Object _DPlugLoadCreate()
            {
                    if(plugValue is null) {
                            plugValue = new " ~ ifname ~"();
                    }
                    return plugValue;
            } 
            
            private __gshared "~ ifname ~ " plugValue = null;";
            return str;
	}

